package org.study.waitnotify;

import java.util.concurrent.TimeUnit;

/**
 * https://blog.csdn.net/qq_40550018/article/details/87859399
 *
 * @author Administrator
 * @date 2021-08-19
 */
public class WaitNotifyAllTest implements Runnable {
    public static void main(String[] args) throws InterruptedException {
        WaitNotifyAllTest testWait = new WaitNotifyAllTest();
        Thread thread = new Thread(testWait, "线程1");
        thread.start();
        Thread thread1 = new Thread(testWait, "线程2");
        thread1.start();
        TimeUnit.SECONDS.sleep(2);
        testWait.setFlag(false);
        Thread thread2 = new Thread(testWait);
        thread2.start();
    }

    private final Object object = new Object();
    private boolean flag = true;

    public boolean isFlag() {
        return flag;
    }

    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        if (flag) {
            synchronized (object) {
                try {
                    System.out.println(Thread.currentThread().getName() + "线程开始执行。。。");
                    TimeUnit.SECONDS.sleep(1);
                    // 1、wait()是Object里面的方法，而不是Thread里面的，这一点很容易搞错。它的作用是将当前线程置于预执行队列，并在wait()所在的代码处停止，等待唤醒通知。
                    // 2、wait()只能在同步代码块或者同步方法中执行，如果调用wait()方法，而没有持有适当的锁，就会抛出异常。
                    // 3、wait()方法调用后悔释放出锁，线程与其他线程竞争重新获取锁。
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "线程执行结束。。。");
            }
        } else {
            synchronized (object) {
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                object.notifyAll();
            }
        }
    }
}
